import { IHttpResponse } from '@ibizstudio/api';
import { AppServiceBase, FetchService, Http } from '@ibizstudio/runtime';
import { SingletonMode } from '../../../decorators/singleton-mode';

interface TipParams {
  srftiptag: string;
  srfdename: string;
  srfkey: string;
}

/**
 * tooltip请求服务
 *
 * @export
 * @class IBzTooltipService
 */
@SingletonMode()
export class IBzTooltipService {
  private http: Http = Http.getInstance();

  /**
   * 在 localStorage 存储的 version 标识
   *
   * @memberof IBzTooltipService
   */
  versionTag = 'ibiz.studio.version';

  /**
   * tip 缓存数据标识
   *
   * @memberof IBzTooltipService
   */
  tipTag = 'ibz-tooltip-cache'

  /**
   * 在 localStorage 存储的 tipCache 缓存数据标识
   *
   * @memberof IBzTooltipService
   */
  tipCacheTag = 'ibz-tooltip-cache';

  /**
   * 环境配置是否加载完成
   *
   * @type {boolean}
   * @memberof IBzTooltipService
   */
  isEnvironmentLoaded: boolean = false

  /**
   * 初始化缓存数据
   *
   * @memberof IBzTooltipService
   */
  initTipCache() {
    const environment = AppServiceBase.getInstance().getAppEnvironment()
    const newVersion = environment?.Version;
    if(newVersion) {
      this.isEnvironmentLoaded = true
      const arr = this.tipCacheTag.split('##')
      let version = null
      if(arr.length > 1) {
        version = arr[arr.length - 1]
      }
      if (!version || (version !== newVersion)) {
        localStorage.removeItem(this.tipCacheTag)
        this.tipCacheTag = this.tipTag + '##' + newVersion
        localStorage.setItem(this.tipCacheTag, JSON.stringify({}))
      }
    }
  }

  constructor() {
    const version = localStorage.getItem(this.versionTag);
    if(version) {
      this.tipCacheTag = this.tipTag + '##' + version
    }
    this.initTipCache()
  }

  /**
   * 基础Api路径
   *
   * @private
   * @memberof IBzTooltipService
   */
  private baseUrl = '/ibizutil';

  /**
   * 加载提示
   *
   * @param {('tag' | 'data')} type
   * @param {*} params
   * @return {*}  {Promise<string | void>}
   * @memberof IBzTooltipService
   */
  async loadTip(params: TipParams): Promise<string | void> {
    if(!this.isEnvironmentLoaded) {
      this.initTipCache()
    }
    const { srftiptag, srfdename, srfkey } = params;
    if (srftiptag) {
      return this.load('tag', srftiptag, params);
    } else if (srfdename && srfkey) {
      return this.load('data', `${srfdename}|${srfkey}`, params);
    }
  }

  /**
   * 加载提示数据
   *
   * @param {('tag' | 'data')} type
   * @param {string} cacheId
   * @param {*} params
   * @return {*}  {Promise<string | void>}
   * @memberof IBzTooltipAsync
   */
  private async load(type: 'tag' | 'data', cacheId: string, params: TipParams): Promise<string | void> {
    const tipCache = localStorage.getItem(this.tipCacheTag);
    let cacheMap: { [key: string]: string } = {};

    if (tipCache) {
      cacheMap = JSON.parse(tipCache);
    }
    const data = cacheMap[cacheId];
    if (data) {
      return data;
    } else {
      let res: IHttpResponse;
      if (type === 'data') {
        res = await this.getDataTooltip(params);
      } else {
        res = await this.getAsyncTooltip(params);
      }
      if (res && res.status === 200 && res.data) {
        const content = res.data.content
        if(content) {
          if (content.indexOf('无法获取指定运行时输入提示') === -1) {
            cacheMap[cacheId] = content;
            localStorage.setItem(this.tipCacheTag, JSON.stringify(cacheMap));
            return content;
          }
        }
      }
    }
  }

  /**
   * 根据提示标识获取提示内容
   *
   * @private
   * @param {{ srftiptag: string }} parmas
   * @return {*}  {Promise<IHttpResponse>}
   * @memberof IBzTooltipService
   */
  private getAsyncTooltip(parmas: { srftiptag: string }): Promise<IHttpResponse> {
    return FetchService.getInstance().post(this.baseUrl + '/gettooltip', parmas);
  }

  /**
   * 根据数据获取当前数据提示内容
   *
   * @private
   * @param {{ srfdename: string, srfkey: string }} params
   * @return {*}  {Promise<IHttpResponse>}
   * @memberof IBzTooltipService
   */
  private getDataTooltip(params: { srfdename: string; srfkey: string }): Promise<IHttpResponse> {
    return this.http.post(this.baseUrl + '/getdatasummary', params);
  }
}
